var PORT_NUMBER = 3000;

var express     = require('express')
    , routes    = require('./routes')
    , nowjs     = require('now')
    , coffee    = require('coffee-script')
    , eyes      = require('eyes')
    , mail      = require('./mail.js')
    , crypto    = require('crypto');
var fs          = require("fs");
var _           = require("./lib/underscore.js");
var alertLeader = require('cron').CronJob;

//-------------------------------------------------------------------------
// Server creation. Startup the server and configure with defualt configs
// found on expressjs's homepage..
//-------------------------------------------------------------------------
var app = module.exports = express.createServer();
sessions = [];


// Configuration
app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({ secret: "banana cake" }));
    app.use(express.methodOverride());
    app.use(require('stylus').middleware({ src: __dirname + '/public' }));
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
    app.use(express.errorHandler());
});

//-------------------------------------------------------------------------
// Helpers. Make life easier in views and controllers.
//-------------------------------------------------------------------------
app.dynamicHelpers({
    session: function (req, res) {return req.session;}
});

app.helpers({
    months: ["Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli",
        "August", "September", "Oktober", "November", "Desember"]
});

//-------------------------------------------------------------------------
// Routes. Set up the routes with some simple code.
//-------------------------------------------------------------------------
app.get('/', routes.index);
for(routeName in routes) {
    var route   = routes[routeName]; // the method
    var url     = route.url || ('/'+routeName);
    var method  = route.method || 'get';
    app[method](url, route);
}


//-------------------------------------------------------------------------
// Now.js. Bind the server to a port and initialize now.js and make
// some functions for the clients to enjoy.
//-------------------------------------------------------------------------
app.listen(PORT_NUMBER);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);

var everyone = nowjs.initialize(app);
var db = require("./database.js");

new alertLeader('00 01 00 * * *', function(){
    var unixtime = parseInt(((new Date).getTime())/1000);//Current time in unixtime
    db.projects.find({phase:"task"}
    ).forEach(function (project) {
            var dateChanged = parseInt(project.dateChanged) || false; //Is dateChanged set
            var messageSent = project.messageSent || false;//Is message sent for this project earlier
            var thirtydays  = 2592000; //30 days in seconds
            if (dateChanged != false && (dateChanged < (unixtime - thirtydays)) && !messageSent){
                var pId         = project._id.toString();
                db.getUserById(project.leader._id,function(err,leader){
                    if(err) console.log(err);
                    else {
                        mail.sendMail(leader.email,"[Midgard] Varsel om utløpt tid på "+project.title,
                            "Du er prosjektleder for <" + project.title + ">, og mottar nå et varsel fordi " +
                            "prosjektet ikke er oppdatert på over 30 dager."+
                            "Vennligst se til at prosjektet blir oppdatert så snart du har mulighet.");
                        db.createEvent({
                            userid: leader._id.toString(),
                            title: "Varsel (Utløpt tid)",
                            desc:  "Prosjektet "+project.title+" er ikke blitt oppdatert på over 30 dager.",
                            state: "task",
                            date: parseInt((new Date).getTime()/1000)
                        });
                        db.editProject({
                            _id:project._id.toString(),
                            messageSent:true,
                            risk:"high"
                        },function(err,success){
                            if (err) throw err;
                            else {
                                console.log(success);
                            }
                        });

                    }
                });

            }
        }, function(err) {
            if(err) throw err;
        });
}, null, true, "Norway/Oslo");



everyone.now.createProject = function(opts, cb) {
    var user = this.user
    eyes.inspect(user)
    
    eyes.inspect(opts, "createProject params");
    db.projects.insert({
        title: opts.title,
        desc:  opts.desc,
        phase: opts.phase || 'idea',
        creator: opts.creator || {id: 'as5d405ads', name: 'Witch Doctor'}
    });
    
    if(cb) {
        db.projects.findOne({title:opts.title,desc:opts.desc}, function(err, project) {
            if (err) throw err;
            if (!project) console.log("no fucking project mate =8");
            console.info("Success! Created project with id: "+project._id.toString());
            eyes.inspect(project, "project");
            cb(project._id.toString());
        });
    }
};


/* !! Deprecated !! */
everyone.now.createEmpty = function(phase, cb) {
    if (!phase) {phase='idea'; console.warn("No phase in 'createEmpty'");}
    db.projects.insert({
        title: "Tittel",
        desc: "Beskrivelse",
        phase: phase,
        blank: true,
        dateCreated: parseInt(Date.now()/1000),
        dateEnd: parseInt(Date.now()/1000)
    });

    db.projects.findOne({blank:true}, function(err, blankProject) {
        blankProject.blank = false;
        db.modifyProject(blankProject._id.toString(), function(p) {p.blank=false;});
        console.info("Calling back");
        cb(blankProject._id.toString());
    });
};

everyone.now.createUser = function(opts) {
    db.users.insert({
        username:   (opts.username).toLowerCase(),
        password:   crypto.createHash('md5').update(opts.password).digest("hex"),
        firstname:  opts.firstname,
        lastname:   opts.lastname,
        email:      opts.email,
        level:      0
    });
    var data = {user:{name:(opts.username).toLowerCase()}};
    db.checkUsername(data, function(err,user) {
        if (user){
            var userId = ""+user._id.toString();
            db.createEvent({
                userid: userId,
                title: "Velkommen",
                desc: "Velkommen "+user.firstname + " " + user.lastname + ", du er nå registrert",
                state: "none",
                date: ((new Date).getTime()/1000)

            });
            mail.sendMail(user.email,"Registrering på Midgard","Hei "+user.firstname + " " + user.lastname+". "+
            "Din registering var vellykket. Ditt brukernavn er ["+ user.username +"]. " +
            "Husk at en administrator må verifisere deg før du får tilgang til "+"all informasjon på nettsiden.");
        }
    });
    console.log("Inserted new user");
};
everyone.now.getProjects = function(opts) {
    var tempClient = this;
    db.getProjects(opts, tempClient);
}

everyone.now.setTheme = function(themeName) {
    eyes.inspect(this.user.session);
}

everyone.now.saveIdeaPosition = function(ideaId,x,y) {
    db.updateIdeaPosition(ideaId,x,y);
    everyone.now.remoteIdeaPositionUpdate(ideaId,x,y);
};

everyone.now.editIdeaForm = function(ideaId, cb) {
    db.getProject(ideaId, function(idea) {
        cb('<h1>'+idea.title+'</h1><p><strong>Title:</strong> '+idea.title+"</p><p><strong>Description:</strong> "+idea.desc+"</p>");
    });
};

everyone.now.addResourceToProject = function(projId, name) {
    // Trying to guess firstname and lastname from fullname. Ex: Jon Petter Jessheim
    var tokens = name.split(" ");
    var last = tokens.pop(); // "Jessheim"
    var first = tokens.shift(); // "Jon"
    var f = function(d) {return new RegExp(d)}
    // This *should* be sufficient.
    db.users.findOne({firstname: f(first), lastname: f(last)}, function(err,obj) {
        if (err) throw err;
        var id = null;
        if (obj) id = obj._id.toString(); // if stuff is found, attach its id =)
        eyes.inspect({name:name, id:id}, 'resource to add')
        db.modifyProject(projId, function(proj) {
            proj.resources = proj.resources || [];
            proj.resources.push({name:name, id:id});
        });
    });
}

everyone.now.setProjectPhase = function(rsc) {
    var id=rsc.id;
    var phase = rsc.phase;
    if(!(id && phase)) return console.error("Missing arguments in setProjectPhase!");
    db.modifyProject(id, function(proj) {
        proj.phase = phase;
    });
}

everyone.now.saveProperties = function(id, properties) {
    properties._id = id;
    eyes.inspect(properties);
    if(properties.dateEnd) {properties.dateEnd = stringToDate(properties.dateEnd)}
    if(properties.dateStart) {properties.dateStart = stringToDate(properties.dateStart)}
    if(properties.dateCreated) {properties.dateCreated = stringToDate(properties.dateCreated)}
    if(properties.leader) {
        console.log("HAS leader, FETCHING it...");
        db.userByName(properties.leader, function(leaderTuple) {
            properties.leader = leaderTuple;
            eyes.inspect(properties);
            db.editProject(properties);
        }); 
    } else {
        console.log("Has NO leader, JUST saving...");
        eyes.inspect(properties);
        db.editProject(properties);
    }
}

// {id:id, property:prop, value:newValue}
everyone.now.setProjectAttribute = function(rsc) {
    var id=rsc.id;
    var attr = rsc.attr;
    var value = rsc.value;
    if(!(id && attr)) return eyes.inspect({attr:attr, value:value, id:id}, "Missing arguments in setProjectAttribute!");
    db.modifyProject(id, function(proj) {
        if (attr == 'dateCreated' || attr == 'dateEnd' || attr == 'dateStart' || attr == 'dateModified') {
            var d_int  = stringToDate(value)
            console.log("d_int = "+d_int);
            proj[attr] = d_int;
        } else {
            proj[attr] = value;
        }
        
        eyes.inspect({attr:attr, value:value});
    });
};

function stringToDate(strDate) {
    var parts = strDate.split('.');
    var dd = parts[0];
    var mm = parts[1];
    var yy = parts[2];
    var americanFormat = mm+'-'+dd+'-'+yy
    eyes.inspect(americanFormat, "American Format")
    return parseInt(Date.parse(americanFormat)/1000);
}


everyone.now.fetchUserList = function(cb) {
    console.log("fetching user list");
    db.getUsers(null, function(userList) {
        // eyes.inspect(userList, "user list");
        userList.forEach(function(e) {e.name=e.firstname+" "+e.lastname});
        userList.forEach(function(e) {e.id=e._id.toString()});
        // cb(_.pick(userList,'name','id'));
        cb(userList);
    });
}

everyone.now.controlUser = function(data, callback) {
    db.checkUsername(data, function(err,result) {
        if (result){
            callback(false);
        }
        else {
            callback(true);
        }
    });
}

everyone.now.removeResourceFromProject = function(rsc) {
    var id = rsc.id;
    var rsc_id = rsc.rsc_id;
    db.modifyProject(id, function(proj) {
        if (!proj) {console.error("proj is null(ish)"); return;}
        eyes.inspect({rsc_id:rsc_id, id:id}, "id|rsc_id");
        proj.resources = proj.resources || [];
        eyes.inspect(proj.resources, "proj.resources @before")
        proj.resources = proj.resources.filter(function(r) {return r.id != rsc_id});
        eyes.inspect(proj.resources, "proj.resources @after ")
    });
}
